﻿namespace HZY.Repository.EntityFramework.Admin;

/// <summary>
/// 后台管理系统数据库上下文
/// </summary>
[DbContextConfig($"Repository.EntityFramework.Admin.Entities.*")]
public class AdminDbContext : DbContext, IBaseDbContext
{
    /// <summary>
    /// 工作单元
    /// </summary>
    public IUnitOfWork UnitOfWork { get; }

    private readonly DbContextConfigAttribute dbContextConfigAttribute;

    private readonly IConfiguration _configuration;
    private readonly IWebHostEnvironment _webHostEnvironment;

    public AdminDbContext(IConfiguration configuration, IWebHostEnvironment webHostEnvironment) : base()
    {
        UnitOfWork = new UnitOfWorkImpl<AdminDbContext>(this);

        dbContextConfigAttribute = this.GetType().GetCustomAttribute<DbContextConfigAttribute>()!;

        _configuration = configuration;
        _webHostEnvironment = webHostEnvironment;
    }

    /// <summary>
    /// 创建配置数据
    /// </summary>
    /// <param name="optionsBuilder"></param>
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var adminRepositoriesOptions = _configuration.GetSection(nameof(AdminRepositoryOptions)).Get<AdminRepositoryOptions>();

        var connectionString = _configuration["ConnectionStrings:" + adminRepositoriesOptions!.DefaultDatabaseType.ToString()];

        switch (adminRepositoriesOptions.DefaultDatabaseType)
        {
            case DefaultDatabaseType.SqlServer:
                optionsBuilder
               .UseSqlServer(connectionString, w => w.MinBatchSize(1).MaxBatchSize(1000))
               ;
                break;
            case DefaultDatabaseType.MySql:
                optionsBuilder
               .UseMySql(connectionString, MySqlServerVersion.LatestSupportedServerVersion, w => w.MinBatchSize(1).MaxBatchSize(1000))
               ;
                break;
            case DefaultDatabaseType.PostgreSql:
                //EnableLegacyTimestampBehavior 启动旧行为，避免时区问题，存储时间报错
                AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
                optionsBuilder
                .UseNpgsql(connectionString, w => w.MinBatchSize(1).MaxBatchSize(1000))
                ;
                break;
            case DefaultDatabaseType.Oracle:
                optionsBuilder
                .UseOracle(connectionString, w => w.MinBatchSize(1).MaxBatchSize(1000))
                ;
                break;
            default:
                break;
        }

        if (_webHostEnvironment.IsDevelopment())
        {
            var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
            // sql 日志写入控制台
            optionsBuilder.UseLoggerFactory(loggerFactory);
        }

        // 懒加载代理
        //options.UseLazyLoadingProxies();
        //添加 EFCore 监控 和 动态表名
        optionsBuilder.AddEntityFrameworkRepositories(adminRepositoriesOptions.IsMonitorEFCore);
        optionsBuilder.AddInterceptors(new AuditInterceptor());
    }

    /// <summary>
    /// 模型创建
    /// </summary>
    /// <param name="modelBuilder"></param>
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        dbContextConfigAttribute!.OnModelCreating(modelBuilder, dbContextConfigAttribute.GetModelTypes(this.GetType()));

        #region 自动迁移种子数据

        ModelBuilderExtensions.Seed(modelBuilder);

        #endregion
    }


}
